#include "mqconfigmanager.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMutexLocker>
#include <QDebug>
#include <QDir>
#include <QCoreApplication>

// 静态成员初始化
MQConfigManager* MQConfigManager::m_instance = nullptr;
QMutex MQConfigManager::m_mutex;

/**
 * @brief 获取配置管理器单例实例
 * @return 配置管理器实例指针
 */
MQConfigManager* MQConfigManager::getInstance()
{
    if (m_instance == nullptr) {
        QMutexLocker locker(&m_mutex);
        if (m_instance == nullptr) {
            m_instance = new MQConfigManager();
        }
    }
    return m_instance;
}

/**
 * @brief 私有构造函数（单例模式）
 */
MQConfigManager::MQConfigManager(QObject *parent)
    : QObject(parent)
{
    // 尝试加载默认配置
    loadConfig();
}

/**
 * @brief 加载配置文件
 * @param configPath 配置文件路径
 * @return 加载是否成功
 */
bool MQConfigManager::loadConfig(const QString& configPath)
{
    QMutexLocker locker(&m_configMutex);
    
    QString fullPath = configPath;
    if (!QDir::isAbsolutePath(configPath)) {
        fullPath = QCoreApplication::applicationDirPath() + "/" + configPath;
    }
    
    QFile file(fullPath);
    if (!file.open(QIODevice::ReadOnly)) {
        QString error = QString("无法打开配置文件: %1").arg(fullPath);
        qWarning() << error;
        emit configLoadError(error);
        return false;
    }
    
    QByteArray data = file.readAll();
    file.close();
    
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
    
    if (parseError.error != QJsonParseError::NoError) {
        QString error = QString("JSON解析错误: %1").arg(parseError.errorString());
        qWarning() << error;
        emit configLoadError(error);
        return false;
    }
    
    if (!doc.isObject()) {
        QString error = "配置文件格式错误：根节点必须是对象";
        qWarning() << error;
        emit configLoadError(error);
        return false;
    }
    
    MQConfig newConfig = parseConfigFromJson(doc.object());
    
    // 验证配置
    auto validation = validateConfig(newConfig);
    if (!validation.first) {
        QString error = QString("配置验证失败: %1").arg(validation.second);
        qWarning() << error;
        emit configLoadError(error);
        return false;
    }
    
    m_config = newConfig;
    emit configChanged();
    
    qDebug() << "配置文件加载成功:" << fullPath;
    return true;
}

/**
 * @brief 保存配置到文件
 * @param configPath 配置文件路径
 * @return 保存是否成功
 */
bool MQConfigManager::saveConfig(const QString& configPath)
{
    QMutexLocker locker(&m_configMutex);
    
    QString fullPath = configPath;
    if (!QDir::isAbsolutePath(configPath)) {
        fullPath = QCoreApplication::applicationDirPath() + "/" + configPath;
    }
    
    QJsonObject jsonObj = configToJson(m_config);
    QJsonDocument doc(jsonObj);
    
    QFile file(fullPath);
    if (!file.open(QIODevice::WriteOnly)) {
        qWarning() << "无法写入配置文件:" << fullPath;
        return false;
    }
    
    file.write(doc.toJson());
    file.close();
    
    qDebug() << "配置文件保存成功:" << fullPath;
    return true;
}

/**
 * @brief 获取当前配置
 * @return 当前配置结构体
 */
MQConfig MQConfigManager::getConfig() const
{
    QMutexLocker locker(&m_configMutex);
    return m_config;
}

/**
 * @brief 设置配置
 * @param config 新的配置结构体
 */
void MQConfigManager::setConfig(const MQConfig& config)
{
    QMutexLocker locker(&m_configMutex);
    m_config = config;
    emit configChanged();
}

/**
 * @brief 获取连接配置
 * @return 连接配置结构体
 */
MQConnectionConfig MQConfigManager::getConnectionConfig() const
{
    QMutexLocker locker(&m_configMutex);
    return m_config.connection;
}

// 性能、可靠性、日志配置方法已移除，相关配置已硬编码到MQClient中

/**
 * @brief 获取业务配置
 * @return 业务配置结构体
 */
MQBusinessConfig MQConfigManager::getBusinessConfig() const
{
    QMutexLocker locker(&m_configMutex);
    return m_config.business;
}

/**
 * @brief 验证配置有效性
 * @param config 要验证的配置
 * @return 验证结果和错误信息
 */
QPair<bool, QString> MQConfigManager::validateConfig(const MQConfig& config) const
{
    // 验证连接配置
    if (config.connection.hostname.isEmpty()) {
        return QPair<bool, QString>(false, "主机名不能为空");
    }
    if (config.connection.port <= 0 || config.connection.port > 65535) {
        return QPair<bool, QString>(false, "端口号必须在1-65535之间");
    }
    if (config.connection.username.isEmpty()) {
        return QPair<bool, QString>(false, "用户名不能为空");
    }

    
    // 性能、可靠性、日志配置验证已移除，相关配置已硬编码
    
    return QPair<bool, QString>(true, "");
}

/**
 * @brief 从JSON对象解析配置
 * @param jsonObj JSON对象
 * @return 解析的配置结构体
 */
MQConfig MQConfigManager::parseConfigFromJson(const QJsonObject& jsonObj) const
{
    MQConfig config;
    
    // 解析连接配置
    QJsonObject connObj = jsonObj["connection"].toObject();
    config.connection.hostname = connObj["hostname"].toString("192.168.10.162");
    config.connection.port = connObj["port"].toInt(5672);
    config.connection.username = connObj["username"].toString("guest");
    config.connection.password = connObj["password"].toString("guest");
    config.connection.vhost = connObj["vhost"].toString("/");

    
    // 性能、可靠性、日志配置解析已移除，相关配置已硬编码
    
    // 解析业务配置
    QJsonObject businessObj = jsonObj["business"].toObject();
    
    // 解析默认交换机配置
    QJsonObject exchangeObj = businessObj["default_exchange"].toObject();
    config.business.defaultExchange.name = exchangeObj["name"].toString("test_exchange");
    config.business.defaultExchange.type = exchangeObj["type"].toString("direct");
    config.business.defaultExchange.durable = exchangeObj["durable"].toBool(true);
    
    // 解析默认队列配置
    QJsonObject queueObj = businessObj["default_queue"].toObject();
    config.business.defaultQueue.name = queueObj["name"].toString("test_queue");
    config.business.defaultQueue.durable = queueObj["durable"].toBool(true);
    config.business.defaultQueue.exclusive = queueObj["exclusive"].toBool(false);
    config.business.defaultQueue.autoDelete = queueObj["auto_delete"].toBool(false);
    
    // 解析默认绑定配置
    QJsonObject bindingObj = businessObj["default_binding"].toObject();
    
    // 解析发布路由键（对应代码中的 routingKey）
    config.business.defaultBinding.routingKey = bindingObj["publish_routing_key"].toString("agv.task.execute");
    
    // 解析队列绑定路由键
    config.business.defaultBinding.queue_routing_key = bindingObj["queue_routing_key"].toString("agv.task.*");
    
    // 向后兼容：如果新字段不存在，使用旧的 routing_key 字段
    if (!bindingObj.contains("publish_routing_key") && bindingObj.contains("routing_key")) {
        config.business.defaultBinding.routingKey = bindingObj["routing_key"].toString("test_key");
    }
    if (!bindingObj.contains("queue_routing_key") && bindingObj.contains("routing_key")) {
        config.business.defaultBinding.queue_routing_key = bindingObj["routing_key"].toString("test_key");
    }
    
    return config;
}

/**
 * @brief 将配置转换为JSON对象
 * @param config 配置结构体
 * @return JSON对象
 */
QJsonObject MQConfigManager::configToJson(const MQConfig& config) const
{
    QJsonObject jsonObj;
    
    // 连接配置
    QJsonObject connObj;
    connObj["hostname"] = config.connection.hostname;
    connObj["port"] = config.connection.port;
    connObj["username"] = config.connection.username;
    connObj["password"] = config.connection.password;
    connObj["vhost"] = config.connection.vhost;

    jsonObj["connection"] = connObj;
    
    // 性能、可靠性、日志配置的JSON生成已移除，相关配置已硬编码
    
    // 业务配置
    QJsonObject businessObj;
    
    // 默认交换机配置
    QJsonObject exchangeObj;
    exchangeObj["name"] = config.business.defaultExchange.name;
    exchangeObj["type"] = config.business.defaultExchange.type;
    exchangeObj["durable"] = config.business.defaultExchange.durable;
    businessObj["default_exchange"] = exchangeObj;
    
    // 默认队列配置
    QJsonObject queueObj;
    queueObj["name"] = config.business.defaultQueue.name;
    queueObj["durable"] = config.business.defaultQueue.durable;
    queueObj["exclusive"] = config.business.defaultQueue.exclusive;
    queueObj["auto_delete"] = config.business.defaultQueue.autoDelete;
    businessObj["default_queue"] = queueObj;
    
    // 默认绑定配置
    QJsonObject bindingObj;
    bindingObj["publish_routing_key"] = config.business.defaultBinding.routingKey;  // routingKey 对应 publish_routing_key
    bindingObj["queue_routing_key"] = config.business.defaultBinding.queue_routing_key;
    businessObj["default_binding"] = bindingObj;
    
    jsonObj["business"] = businessObj;
    
    return jsonObj;
}
